package com.wudizaba.microservicesdemosystem.util;


import cn.hutool.core.convert.Convert;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.WriteTable;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.BorderStyle;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

/**
 * easyexcel工具类 -- Excel解析
 */
@Slf4j
public class EasyExcelUtil {


    /**
     * 读取Excel（多个sheet可以用同一个实体类解析）
     *
     * @param excelInputStream
     * @param fileName
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> List<T> readExcel(InputStream excelInputStream, String fileName, Class<T> clazz) {
        ExcelListener excelListener = new ExcelListener();
        ExcelReader excelReader = getReader(excelInputStream, fileName, clazz, excelListener);
        if (excelReader == null) {
            return new ArrayList<>();
        }
        List<ReadSheet> readSheetList = excelReader.excelExecutor().sheetList();
        for (ReadSheet readSheet : readSheetList) {
            excelReader.read(readSheet);
        }
        excelReader.finish();
        return Convert.toList(clazz, excelListener.getDataList());
    }

    /**
     * 导出Excel(一个sheet)
     *
     * @param response  HttpServletResponse
     * @param list      数据list
     * @param fileName  导出的文件名
     * @param sheetName 导入文件的sheet名
     * @param clazz     实体类
     */
    public static <T> void writeExcel(HttpServletResponse response, List<T> list, String fileName, String sheetName, WriteTable writeTable, Class<T> clazz) {
        OutputStream outputStream = null;
        ExcelWriter excelWriter = null;
        try {
            outputStream = getOutputStream(response, fileName);
            excelWriter = EasyExcel.write(outputStream, clazz).build();
            WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).build();
            excelWriter.write(list, writeSheet, writeTable);
            outputStream.flush();
        } catch (Exception e) {
            log.error("excel文件导出失败, 失败原因：{}", e.getMessage());
            e.printStackTrace();
        } finally {
            try {
                if (excelWriter != null) {
                    excelWriter.finish();
                }

                if (outputStream != null) {
                    outputStream.close();
                }

            } catch (IOException e) {
                log.error("excel文件导出失败, 失败原因：{}", e);
            }
        }
    }

    public static <T> void writeExcel(HttpServletResponse response, List<T> list, String fileName, String sheetName, Class<T> clazz) {
        OutputStream outputStream = null;
        ExcelWriter excelWriter = null;
        try {
            outputStream = getOutputStream(response, fileName);
            WriteCellStyle wr = new WriteCellStyle();
            wr.setBorderLeft(BorderStyle.THIN);//细实线
            wr.setBorderTop(BorderStyle.THIN);
            wr.setBorderRight(BorderStyle.THIN);
            wr.setBorderBottom(BorderStyle.THIN);
            HorizontalCellStyleStrategy ho = new HorizontalCellStyleStrategy(wr, wr);
            excelWriter = EasyExcel.write(outputStream, clazz)
                    .registerWriteHandler(new SimpleColumnWidthStyleStrategy(30))
                    .registerWriteHandler(ho)
                    .build();
            WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).build();
            excelWriter.write(list, writeSheet);
            outputStream.flush();
        } catch (Exception e) {
            log.error("excel文件导出失败, 失败原因：{}", e.getMessage());
            e.printStackTrace();
        } finally {
            try {
                if (excelWriter != null) {
                    excelWriter.finish();
                }

                if (outputStream != null) {
                    outputStream.close();
                }

            } catch (IOException e) {
                log.error("excel文件导出失败, 失败原因：{}", e);
            }
        }
    }

    public static <T> void writeExcel(HttpServletResponse response, List<List<String>> list, String fileName, String sheetName, List<List<String>> head) {
        OutputStream outputStream = null;
        ExcelWriter excelWriter = null;
        try {
            outputStream = getOutputStream(response, fileName);
//            excelWriter = EasyExcel.write(outputStream).head(head).build();
//            excelWriter = EasyExcel.write(outputStream).head(head).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).build();
            //设置表格框线
            WriteCellStyle wr = new WriteCellStyle();
            wr.setBorderLeft(BorderStyle.THIN);//细实线
            wr.setBorderTop(BorderStyle.THIN);
            wr.setBorderRight(BorderStyle.THIN);
            wr.setBorderBottom(BorderStyle.THIN);
            HorizontalCellStyleStrategy ho = new HorizontalCellStyleStrategy(wr, wr);
//
            excelWriter = EasyExcel.write(outputStream).head(head)
                    .registerWriteHandler(new SimpleColumnWidthStyleStrategy(30))
                    .registerWriteHandler(ho).build();
            WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).build();
            excelWriter.write(list, writeSheet);
            outputStream.flush();
        } catch (Exception e) {
            log.error("excel文件导出失败, 失败原因：{}", e.getMessage());
            e.printStackTrace();
        } finally {
            try {
                if (excelWriter != null) {
                    excelWriter.finish();
                }

                if (outputStream != null) {
                    outputStream.close();
                }

            } catch (IOException e) {
                log.error("excel文件导出失败, 失败原因：{}", e);
            }
        }
    }


    /**
     * 导出时生成OutputStream
     */
    private static OutputStream getOutputStream(HttpServletResponse response, String fileName) {
        //创建本地文件
        try {
            fileName = URLEncoder.encode(fileName, "UTF-8");
            response.setHeader("Content-Disposition",
                    "attachment;filename=\"" + new String(fileName.getBytes(), "ISO-8859-1") + ".xlsx\"");
            response.setContentType("application/vnd.ms-excel;charset=UTF-8");
            return response.getOutputStream();
        } catch (IOException e) {
            log.error("excel文件导出失败, 失败原因：{}", e);
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 返回ExcelReader
     */
    private static <T> ExcelReader getReader(InputStream inputStream, String filename, Class<T> clazz, ExcelListener excelListener) {
        try {
            if (filename == null ||
                    (!filename.toLowerCase().endsWith(".xls") && !filename.toLowerCase().endsWith(".xlsx"))) {
                return null;
            }
            ExcelReader excelReader = EasyExcel.read(inputStream, clazz, excelListener).build();
            inputStream.close();
            return excelReader;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


}
